package hello.word.m2.maven.dao;

import ca.pjer.spring.boot.jdbi.AutoSqlObject;
import hello.word.m2.maven.domain.Book;
import hello.word.m2.maven.jpa.BindJpql;
import hello.word.m2.maven.locator.JdbiSqlObjectClasspathLocator;
import hello.word.m2.maven.support.CrudDao;
import org.jdbi.v3.core.statement.OutParameters;
import org.jdbi.v3.sqlobject.customizer.Bind;
import org.jdbi.v3.sqlobject.customizer.Define;
import org.jdbi.v3.sqlobject.customizer.OutParameter;
import org.jdbi.v3.sqlobject.statement.SqlCall;
import org.jdbi.v3.sqlobject.statement.SqlQuery;
import org.jdbi.v3.sqlobject.statement.SqlUpdate;
import org.jdbi.v3.stringtemplate4.UseStringTemplateEngine;

import java.util.List;
//@AutoSqlObject
public interface BookDao extends CrudDao<Book, Long> {

	@SqlUpdate("insert into t_book(id, name) values (:id, :name)")
	int insert(long id, String name);

	@SqlUpdate("update t_book set name = :name where id = :id")
	int update(long id, String name);

	@SqlQuery("select * from t_book")
//	@RegisterBeanMapper(Book.class)
	List<Book> selectAll();

	@SqlQuery("select * from t_book where id= :id and name = :name")
	List<Book> selectByIdAndName(long id, String name);

//	@UseClasspathSqlLocator
	@JdbiSqlObjectClasspathLocator
	@SqlQuery("complexSql")
	List<Book> selectAll2();

	@UseStringTemplateEngine
	@SqlQuery("select id, name, publish_datetime from t_book order by <if(sort)> <sortBy> desc, <endif> id desc")
	List<Book> selectAll(@Define boolean sort, @Define String sortBy);

	/**
	 * @note:条件表达式中，条件只支持true或false这两种方式，若是传入的内容为null，则当中false处理，表达式无法支持name=="parrt"这种运算形式的内如。
	 */
	@UseStringTemplateEngine
	@SqlQuery("select id, name, publish_datetime from t_book order by <if(name)> <sortBy> desc, <endif> id desc")
	List<Book> selectAll(@Define String name, @Define String sortBy);

//	@UseStringTemplateEngine
//	@SqlUpdate("insert into book(<book.notNullProperties>) values(<book.notNullValues>)")
//	int insert(@Define Book book);

	@SqlCall("{call inout_param(:p_inout)}")
	void callDemoProceduce(@Bind("p_inout") int p_inout);
	
	@SqlCall("{call inout_param(:p_inout)}")
	@OutParameter(name = "p_inout", sqlType = java.sql.Types.INTEGER)
	OutParameters callDemoProceduce2(@Bind("p_inout") int p_inout);


	@BindJpql
	public List<Book> findByIdOrFirstName(Long id, String name);

	@BindJpql
	public List<Book> findById(Long id);

	@BindJpql
	public List<Book> findByFirstNameLike(String name);
}
